package center.leon.zooredisson.monkey.controller;

import center.leon.zoocommon.common.Response;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author : Leon on XXM Mac
 * @since : create in 2024/9/25 11:52
 */
@Slf4j
@RestController
@RequestMapping(value = "/monkey")
public class MonkeyController {

    @Resource
    private RedissonClient redissonClient;

    @SneakyThrows
    @PostMapping(value = "/lock")
    public Response<String> lock(@RequestParam(value = "name", defaultValue = "World") String name) {
        lockHarryUp(name + "-0");
        lockHarryUp(name + "-1");
        log.info("semaphore-main- {} - {} ", Thread.currentThread().getName(), name);
        return Response.success("Hello ".concat(name));
    }

    @SneakyThrows
    @Async
    public void lockHarryUp(String name){
        log.info("lock-sub-in- {} - {} ", Thread.currentThread().getName(), name);
        RLock rLock = redissonClient.getLock("MONKEY_LOCK");
        try {
            rLock.lock();
            rLock.lock();
            TimeUnit.SECONDS.sleep(10);
        }finally {
            rLock.unlock();
            rLock.unlock();
        }
        log.info("lock-sub-ou- {} - {} ", Thread.currentThread().getName(), name);
    }

    @SneakyThrows
    @PostMapping(value = "/tryLock")
    public Response<String> tryLock(@RequestParam(value = "name", defaultValue = "World") String name) {
        tryLockHarryUp(name + "-0");
        tryLockHarryUp(name + "-1");
        log.info("semaphore-main- {} - {} ", Thread.currentThread().getName(), name);
        return Response.success("Hello ".concat(name));
    }

    @SneakyThrows
    @Async
    public void tryLockHarryUp(String name){
        log.info("tryLock-sub-in- {} - {} ", Thread.currentThread().getName(), name);
        RLock rLock = redissonClient.getLock("MONKEY_TRYLOCK");
        try {
            boolean tryLock = rLock.tryLock();
            if(tryLock) {
                TimeUnit.SECONDS.sleep(100);
            }
        }finally {
            if(rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        log.info("tryLock-sub-ou- {} - {} ", Thread.currentThread().getName(), name);
    }


    @SneakyThrows
    @PostMapping(value = "/semaphore")
    public Response<String> semaphore(@RequestParam(value = "name", defaultValue = "World") String name) {
        RSemaphore semaphore = redissonClient.getSemaphore("MONKEY_SEMAPHORE");
        semaphore.trySetPermits(1);
        boolean acquire = semaphore.tryAcquire(1);
        if(acquire){

        }
        log.info("semaphore-main- {} - {} ", Thread.currentThread().getName(), name);
        return Response.success("Hello ".concat(Boolean.toString(acquire)));
    }

    @SneakyThrows
    @Async
    public void acquireHarryUp(String name){
        TimeUnit.SECONDS.sleep(2);
        log.info("semaphore-sub- {} - {} ", Thread.currentThread().getName(), name);
    }
}
